home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume9 / teco / part01 next >
Encoding:
Internet Message Format  |  1987-03-11  |  55.6 KB

  1. Subject:  v09i028:  A TECO text editor, Part01/04
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: genrad!mlf
  6. Mod.sources: Volume 9, Issue 28
  7. Archive-name: teco/Part01
  8.  
  9.  
  10. This is TECO for Ultrix, part 1.  It consists of nine files:
  11. manpage.doc (the "man" page), teco.doc (an overview of what it is),
  12. maketeco.doc (how to build it), teco_data.doc (once through TECO's
  13. data storage), makefile, .tecorc (an example of the startup file)
  14. te_defs.h (header file), te_data.c (global data), te_main.c (main).
  15.  
  16. [ I diddled with the Makefile a bit, renamed .tecorc to dot.tecorc,
  17.   and packed things up into shell archives.  Better documentation
  18.   is encouraged -- any "old-timers" wanna write it? -- as would be
  19.   support for TERMCAP or CURSES; send changes to genrad!mlf --r$ ]
  20.  
  21. #! /bin/sh
  22. # This is a shell archive.  Remove anything before this line,
  23. # then unpack it by saving it in a file and typing "sh file".
  24. # If this archive is complete, you will see the message:
  25. #        "End of archive 1 (of 4)."
  26. # Contents:  MANIFEST Makefile dot.tecorc maketeco.doc manpage.doc
  27. #   te_data.c te_exec0.c te_main.c te_rdcmd.c te_utils.c teco.doc
  28. #   teco_data.doc
  29. # Wrapped by rs@mirror on Thu Mar 12 19:54:25 1987
  30. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  31. echo shar: Extracting \"MANIFEST\" \(684 characters\)
  32. if test -f MANIFEST ; then 
  33.   echo shar: Will not over-write existing file \"MANIFEST\"
  34. else
  35. sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
  36. X   File Name        Archive #    Description
  37. X-----------------------------------------------------------
  38. X MANIFEST                  1    This shipping list
  39. X Makefile                  1    
  40. X dot.tecorc                1    
  41. X maketeco.doc              1    
  42. X manpage.doc               1    
  43. X te_chario.c               2    
  44. X te_data.c                 1    
  45. X te_defs.h                 2    
  46. X te_exec0.c                1    
  47. X te_exec1.c                3    
  48. X te_exec2.c                3    
  49. X te_main.c                 1    
  50. X te_rdcmd.c                1    
  51. X te_srch.c                 2    
  52. X te_subs.c                 2    
  53. X te_utils.c                1    
  54. X te_window.c               4    
  55. X teco.doc                  1    
  56. X teco_data.doc             1    
  57. END_OF_MANIFEST
  58. if test 684 -ne `wc -c <MANIFEST`; then
  59.     echo shar: \"MANIFEST\" unpacked with wrong size!?
  60. fi
  61. # end of overwriting check
  62. fi
  63. echo shar: Extracting \"Makefile\" \(518 characters\)
  64. if test -f Makefile ; then 
  65.   echo shar: Will not over-write existing file \"Makefile\"
  66. else
  67. sed "s/^X//" >Makefile <<'END_OF_Makefile'
  68. X##
  69. X##  TECO MAKEFILE
  70. X##
  71. X
  72. X# Debugging or optimizing?
  73. X#CFLAGS    = -g
  74. XCFLAGS    = -O
  75. XTERMCAP    = -ltermcap
  76. X
  77. XOBJECTS    = te_data.o te_exec0.o te_exec1.o te_exec2.o te_main.o te_rdcmd.o \
  78. X    te_srch.o te_subs.o te_utils.o te_window.o
  79. X
  80. Xte:        $(OBJECTS) te_chario.o
  81. X    $(CC) -o te $(CFLAGS) $(OBJECTS) te_chario.o $(TERMCAP)
  82. X
  83. Xtex:        $(OBJECTS) te_chx.o
  84. X    $(CC) -o tex $(CFLAGS) $(OBJECTS) te_chx.o $(TERMCAP)
  85. X
  86. X$(OBJECTS) te_chario.o te_chx.o:    te_defs.h
  87. Xte_chx.o:                te_chario.c
  88. X    cp te_chario.c te_chx.c
  89. X    $(CC) -DDEBUG $(CFLAGS) -c te_chx.c
  90. X
  91. END_OF_Makefile
  92. if test 518 -ne `wc -c <Makefile`; then
  93.     echo shar: \"Makefile\" unpacked with wrong size!?
  94. fi
  95. # end of overwriting check
  96. fi
  97. echo shar: Extracting \"dot.tecorc\" \(259 characters\)
  98. if test -f dot.tecorc ; then 
  99.   echo shar: Will not over-write existing file \"dot.tecorc\"
  100. else
  101. sed "s/^X//" >dot.tecorc <<'END_OF_dot.tecorc'
  102. X!!!!!!   THIS IS A SAMPLE FILE.  REPLACE ^[ with ESCAPE, and ^A/^E with
  103. X!!!!!!   THEIR REAL CONTROL CHARACTERS, AND DELETE THESE TWO LINES.
  104. X@ei// hk 64ez :qz-3"g gz j:s ^["s
  105. X0k hxz hk 
  106. X:eb^Eqz^[ "e
  107. X^AFile not found: ^A :g* ^A
  108. X^A hkekex '
  109. Xy'' 5,7:w 0,0xz
  110. X^[^[
  111. END_OF_dot.tecorc
  112. if test 259 -ne `wc -c <dot.tecorc`; then
  113.     echo shar: \"dot.tecorc\" unpacked with wrong size!?
  114. fi
  115. # end of overwriting check
  116. fi
  117. echo shar: Extracting \"maketeco.doc\" \(2478 characters\)
  118. if test -f maketeco.doc ; then 
  119.   echo shar: Will not over-write existing file \"maketeco.doc\"
  120. else
  121. sed "s/^X//" >maketeco.doc <<'END_OF_maketeco.doc'
  122. XTECO for Ultrix            Matt Fichtenbaum  3/27/86  revised 7/25/86
  123. X
  124. X     These notes describe briefly what it is and how to make it.
  125. X
  126. X     Ultrix TECO is an editor that is mostly compatible with DEC
  127. XStandard TECO.  It is written in C to run under Ultrix (and other
  128. XUnix (tm) implementations, e.g., it has compiled and run on a Sun
  129. Xworkstation).  It implements all the editor functions of DEC TECO
  130. Xand it has some additional features suited to the Unix environment,
  131. Xsuch as the ability to execute Unix commands or to pass text from
  132. XTECO's buffer through a Unix process and incorporate the result
  133. Xinto the text buffer.  It lacks some of the display support features
  134. Xof Standard TECO, but includes the split-screen "window" mode
  135. Xsuitable for using "raw" TECO.
  136. X
  137. X     Note that TECO's CRT routines are hard-coded for a VT100-type
  138. Xterminal.  Using another type of terminal requires changing these
  139. Xroutines.
  140. X
  141. X     Ultrix TECO consists of twelve source files:
  142. X
  143. X    te_defs.h    definitions file #include'd by the .c files
  144. X    te_data.c    "common" data
  145. X    te_main.c    main program
  146. X    te_rdcmd.c    read commands and build the command string
  147. X    te_exec0.c    exec commands 1 (initial dispatch & expressions)
  148. X    te_exec1.c    exec commands 2 (most commands)
  149. X    te_exec2.c    exec commands 3 (E, F commands, file I/O, Unix extensions)
  150. X    te_srch.c    search operations
  151. X    te_window.c    CRT display routines
  152. X    te_chario.c    terminal I/O, interaction with tty driver, signals
  153. X    te_subs.c    higher level subroutines
  154. X    te_utils.c    lower level subroutines
  155. X
  156. XTECO is built as follows:
  157. X
  158. X    1. Compile all the .c files with cc -c -O <file>.c
  159. X
  160. X    2. Link all the object files with cc -o te *.o
  161. X
  162. XNote that TECO catches the "interrupt" (^C) signal; this may cause problems when
  163. Xusing dbx.  This can be circumvented by compiling te_chario.c with the symbol
  164. XDEBUG defined, i.e.,
  165. X
  166. X    cc -c -g -DDEBUG te_chario.c
  167. X
  168. X(naturally, the -g flag should be specified to all the cc commands
  169. Xif dbx is to be used).
  170. X
  171. X
  172. XThere are two 'makefiles.'  'makefile' makes 'te' as above; 'makefile.x'
  173. Xmakes 'te' and 'tex' for use with dbx.  'tex' compiles te_chario.c with
  174. Xthe DEBUG flag set.  Because 'makefile.x' compiles with -g and 'makefile'
  175. Xdoesn't, the two ought not to share the same directory.
  176. X
  177. XNOTE: makefile.x is set up to make the -DDEBUG version of te_chario.o
  178. Xunder the name te_chx.o.  The source directory should contain te_chx.c
  179. Xas a symbolic link to te_chario.c.
  180. X
  181. X    The file .tecorc illustrates one possible startup.  It implements
  182. X'te file' to mean
  183. X
  184. X    %te
  185. X    *ebfile$y5,7:w$$
  186. X
  187. END_OF_maketeco.doc
  188. if test 2478 -ne `wc -c <maketeco.doc`; then
  189.     echo shar: \"maketeco.doc\" unpacked with wrong size!?
  190. fi
  191. # end of overwriting check
  192. fi
  193. echo shar: Extracting \"manpage.doc\" \(1285 characters\)
  194. if test -f manpage.doc ; then 
  195.   echo shar: Will not over-write existing file \"manpage.doc\"
  196. else
  197. sed "s/^X//" >manpage.doc <<'END_OF_manpage.doc'
  198. XNAME
  199. X    te - TECO text editor
  200. X
  201. XSYNOPSIS
  202. X    te [filename]
  203. X
  204. XDESCRIPTION
  205. X    te is an implementation of TECO written in C to run under
  206. X    Ultrix 1.2.
  207. X
  208. X    te implements DEC standard TECO, with some exceptions
  209. X    described below, plus some extensions for the Ultrix
  210. X    environment.
  211. X
  212. X    te assumes a VT100-type terminal, and its display
  213. X    driver is hard-coded for such.
  214. X
  215. XDOCUMENTATION
  216. X    The DEC Standard TECO book describes the basic editing
  217. X    functions of TECO.  teco.doc describes the differences
  218. X    between te and standard TECO, including the extensions
  219. X    for the Ultrix environment.  maketeco.doc describes the
  220. X    files that comprise te, and the build procedure.
  221. X
  222. XFILES
  223. X    ~/.tecorc    editor startup file
  224. X    <file>.tmp    temporary output file(s)
  225. X    <file>.bak    previous version of edited file
  226. X    /etc/termcap    describes terminal (used only to find width of VT100)
  227. X
  228. XAUTHOR
  229. X    Matt Fichtenbaum, GenRad Inc., Concord, Mass.
  230. X
  231. XBUGS
  232. X    te acquires memory for its buffer using malloc(), but
  233. X    never returns the space.  This can cause the task in
  234. X    memory to appear to be larger than it is.
  235. X
  236. X    Several of the standard display features of TECO, most
  237. X    notably the -256+n:W command used by interpretive editing
  238. X    macros, are unimplemented.  There are undoubtedly some
  239. X    subtle bugs in the display handler for the features that
  240. X    are implemented.
  241. X
  242. END_OF_manpage.doc
  243. if test 1285 -ne `wc -c <manpage.doc`; then
  244.     echo shar: \"manpage.doc\" unpacked with wrong size!?
  245. fi
  246. # end of overwriting check
  247. fi
  248. echo shar: Extracting \"te_data.c\" \(7350 characters\)
  249. if test -f te_data.c ; then 
  250.   echo shar: Will not over-write existing file \"te_data.c\"
  251. else
  252. sed "s/^X//" >te_data.c <<'END_OF_te_data.c'
  253. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  254. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  255. X/* They may be copied if this copyright notice is included                    */
  256. X
  257. X/* te_data.c global variables  12/31/85 */
  258. X
  259. X#include "te_defs.h"
  260. X
  261. X/* error message text */
  262. Xchar *errors[] =
  263. X    {
  264. X    "> not in iteration",
  265. X    "Can't pop Q register",
  266. X    "Can't open output file ",
  267. X    "File not found ",
  268. X    "Invalid E character",
  269. X    "Invalid F character",
  270. X    "Invalid insert arg",
  271. X    "Invalid command",
  272. X    "Invalid number",
  273. X    "Invalid P arg",
  274. X    "Invalid \" character",
  275. X    "Invalid Q-reg name",
  276. X    "Invalid radix arg",
  277. X    "Invalid search arg",
  278. X    "Invalid search string",
  279. X    "Invalid ^ character",
  280. X    "Insufficient memory available",
  281. X    "Missing )",
  282. X    "No arg before ^_",
  283. X    "No arg before ,",
  284. X    "No arg before =",
  285. X    "No arg before )",
  286. X    "No arg before \"",
  287. X    "No arg before ;",
  288. X    "No arg before U",
  289. X    "No file for input",
  290. X    "No file for output",
  291. X    "Numeric arg with Y",
  292. X    "Output file already open",
  293. X    "Pushdown list overflow",
  294. X    "Pointer off page",
  295. X    "; not in iteration",
  296. X    "Search failure ",
  297. X    "String too long",
  298. X    "Unterminated command",
  299. X    "Unterminated macro",
  300. X    "Execution interrupted",
  301. X    "Y command suppressed",
  302. X    "Invalid W arg",
  303. X    "Numeric arg with FR",
  304. X    "Internal error",
  305. X    "EOF read from std input",
  306. X    "Invalid A arg",
  307. X    "Ambiguous file specification ",
  308. X    "System fork or pipe error"
  309. X    } ;
  310. X /* declare global variables */
  311. X    struct buffcell *freebuff = NULL;        /* buffcell free-list pointer */
  312. X    struct buffcell *dly_freebuff = NULL;    /* delayed free-list pointer */
  313. X    struct qp *freedcell = NULL;            /* cell free-list pointer */
  314. X
  315. X/* the text buffer header */
  316. X    struct qh buff = { NULL, NULL, 0, 0 } ;
  317. X
  318. X/* the q-register headers point to the start of the buffer and registers */
  319. X    struct qh qreg[NQREGS+5];        /* for q regs, command, search, file, sys-command, time/date */
  320. X
  321. X/* the q-register stack contains temporary copies of q-register contents */
  322. X    struct qh qstack[QSTACKSIZE];    /* q-reg stack */
  323. X    struct qh *qsp;                    /* q-reg stack pointer */
  324. X
  325. X/* the macro stack contains pointers to the currently active macros. */
  326. X/* the top of the stack is the command pointer */
  327. X    struct qp mstack[MSTACKSIZE];    /* macro stack */
  328. X    struct qp *msp;                    /* macro stack pointer */
  329. X
  330. X/* the expression stack */
  331. X    struct exp_entry estack[ESTACKSIZE];    /* expression stack */
  332. X    struct exp_entry *esp;                    /* expression stack pointer */
  333. X
  334. X/* global variables, etc. */
  335. X
  336. Xint char_count = 0;                    /* char count for tab typer            */
  337. Xchar lastc = ' ';                    /* last char read                    */
  338. Xint ttyerr;                            /* error return from ioctl            */
  339. Xextern int errno;                    /* system error code                */
  340. Xstruct sgttyb ttybuf;                /* local copy of tty control data    */
  341. Xjmp_buf xxx;                        /* preserved environment for error restart */
  342. Xint err;                            /* local error code                    */
  343. Xstruct qp t_qp;                        /* temporary buffer pointer            */
  344. Xstruct qp aa, bb, cc;                /* more temporaries                    */
  345. Xstruct buffcell t_bcell;            /* temporary bcell                    */
  346. Xint tabmask = 7;                    /* mask for typing tabs                */
  347. Xint exitflag;                        /* flag for ending command str exec    */
  348. Xchar term_char = ESC;                /* terminator for insert, search, etc.    */
  349. Xchar cmdc;                            /* current command character        */
  350. Xchar skipc;                            /* char found by "skipto()"            */
  351. Xint dot, z, tdot;                    /* current, last, temp buffer position    */
  352. Xint ins_count;                        /* count of chars inserted            */
  353. Xint ll, mm, nn;                        /* general temps                    */
  354. Xint ctrl_e = 0;                        /* form feed flag                    */
  355. Xint ctrl_r = 10;                    /* numeric radix (8, 10, 16)        */
  356. Xint ctrl_s = 0;                        /* string length for S, I, G        */
  357. Xint ctrl_x = 0;                        /* search mode flag                    */
  358. Xint ed_val = 0;                        /* ED value                            */
  359. Xint es_val = 0;                        /* ES value                            */
  360. Xint et_val = 518;                    /* ET value                            */
  361. Xint eu_val = -1;                    /* EU value                            */
  362. Xint ev_val = 0;                        /* EV value                            */
  363. Xint ez_val = 0;                        /* EZ value                            */
  364. Xint srch_result = 0;                /* result of last :S executed        */
  365. Xint atflag = 0;                        /* flag for @ char typed            */
  366. Xint colonflag = 0;                    /* flag for : char typed            */
  367. Xint trace_sw = 0;                    /* nonzero if tracing command exec    */
  368. X
  369. Xstruct buffcell *insert_p;            /* pointer to temp buffer segment during insert */
  370. Xint buff_mod;                        /* set to earliest buffer change    */
  371. Xint search_flag;                    /* set nonzero by search            */
  372. X /* character mapping table (direct) */
  373. Xchar mapch[] =
  374. X{
  375. X 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,        /* ^@ - ^M */
  376. X16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,        /* ^N - ^_ */
  377. X' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',        /* sp - /  */
  378. X'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',        /* 0 - ?   */
  379. X'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',        /* @ - O   */
  380. X'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_',        /* P - _   */
  381. X'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',        /* ` - o   */
  382. X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|','}', '~', 0177        /* p - del */
  383. X} ;
  384. X
  385. X/* character table (mapped to lower case) */
  386. Xchar mapch_l[] =
  387. X{
  388. X 0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,        /* ^@ - ^M */
  389. X16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,        /* ^N - ^_ */
  390. X' ', '!', '"', '#', '$', '%', '&', '\'','(', ')', '*', '+', ',', '-', '.', '/',        /* sp - /  */
  391. X'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',        /* 0 - ?   */
  392. X'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',        /* @ - O   */
  393. X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\',']', '^', '_',        /* P - _   */
  394. X'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',        /* ` - o   */
  395. X'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|','}', '~', 0177        /* p - del */
  396. X} ;
  397. X /* table of special characters for "search," "skipto()," and "lines()"    */
  398. X/* see "te_defs.h for meaning of bits */
  399. X
  400. Xchar spec_chars[] =
  401. X{
  402. X0,            A_S,        0,            0,                /* ^@ ^A ^B ^C */
  403. X0,            A_A,        0,            0,                /* ^D ^E ^F ^G */
  404. X0,            A_T,        A_L,        A_L,            /* ^H ^I ^J ^K */
  405. XA_L,        0,            A_A,        0,                /* ^L ^M ^N ^O */
  406. X0,            A_A,        A_A,        A_A,            /* ^P ^Q ^R ^S */
  407. X0,            A_T|A_Q,    0,            0,                /* ^T ^U ^V ^W */
  408. XA_A,        0,            0,            0,                /* ^X ^Y ^Z ^[ */
  409. X0,            0,            A_S,        0,                /* ^\ ^] ^^ ^_ */
  410. X0,            A_S,        A_X,        0,                /*    !  "  #  */
  411. X0,            0,            0,            A_X,            /* $  %  &  '  */
  412. X0,            0,            0,            0,                /* (  )  *  +  */
  413. X0,            0,            0,            0,                /* ,  -  .  /  */
  414. X0,            0,            0,            0,                /* 0  1  2  3  */
  415. X0,            0,            0,            0,                /* 4  5  6  7  */
  416. X0,            0,            0,            0,                /* 8  9  :  ;  */
  417. XA_X,        0,            A_X,        0,                /* <  =  >  ?  */
  418. XA_S,        0,            A_E|A_F,    0,                /* @  A  B  C  */
  419. X0,            A_S,        A_S,        A_Q,            /* D  E  F  G  */
  420. X0,            A_T|A_E,    0,            0,                /* H  I  J  K  */
  421. X0,            A_Q,        A_T|A_F,    A_T,            /* L  M  N  O  */
  422. X0,            A_Q,        A_E,        A_T|A_F,        /* P  Q  R  S  */
  423. X0,            A_Q,        0,            A_E,            /* T  U  V  W  */
  424. XA_Q,        0,            0,            A_Q,            /* X  Y  Z  [  */
  425. X0,            A_Q,        A_S,        A_T|A_E,        /* \  ]  ^  _  */
  426. X0,            0,            A_E|A_F,    0,                /* `  a  b  c  */
  427. X0,            A_S,        A_S,        A_Q,            /* d  e  f  g  */
  428. X0,            A_T|A_E,    0,            0,                /* h  i  j  k  */
  429. X0,            A_Q,        A_T|A_F,    A_T,            /* l  m  n  o  */
  430. X0,            A_Q,        A_E,        A_T|A_F,        /* p  q  r  s  */
  431. X0,            A_Q,        0,            A_E,            /* t  u  v  w  */
  432. XA_Q,        0,            0,            0,                /* x  y  z  {  */
  433. XA_X,        0,            0,            0,                /* |  }  ~  del */
  434. X} ;
  435. X
  436. END_OF_te_data.c
  437. if test 7350 -ne `wc -c <te_data.c`; then
  438.     echo shar: \"te_data.c\" unpacked with wrong size!?
  439. fi
  440. # end of overwriting check
  441. fi
  442. echo shar: Extracting \"te_exec0.c\" \(5458 characters\)
  443. if test -f te_exec0.c ; then 
  444.   echo shar: Will not over-write existing file \"te_exec0.c\"
  445. else
  446. sed "s/^X//" >te_exec0.c <<'END_OF_te_exec0.c'
  447. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  448. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  449. X/* They may be copied if this copyright notice is included                    */
  450. X
  451. X/* te_exec0.c   execute command string   11/31/86 */
  452. X#include "te_defs.h"
  453. X#include <sys/time.h>
  454. X
  455. Xexec_cmdstr()
  456. X    {
  457. X    char c;
  458. X    int digit_sw;
  459. X    struct tm *timeptr;
  460. X    char *timestring, *asctime();
  461. X    struct timeval timevalue, tzvalue;
  462. X
  463. X    exitflag = 0;                    /* set flag to "executing" */
  464. X    cmdstr.p = cbuf.f;                /* cmdstr to start of command string */
  465. X    cmdstr.z = cbuf.z;
  466. X    cmdstr.flag = cmdstr.dot = cmdstr.c = 0;    /* clear char ptr and iteration flag */
  467. X    msp = &cmdstr;                    /* initialize macro stack pointer */
  468. X    esp = &estack[0];                /* initialize expression stack pointer */
  469. X    qsp = &qstack[-1];                /* initialize q-reg stack pointer */
  470. X    atflag = colonflag = 0;            /* clear flags */
  471. X    esp->flag2 = esp->flag1 = 0;    /* initialize expression reader */
  472. X    esp->op = OP_START;
  473. X    trace_sw = 0;                    /* start out with trace off */
  474. X    digit_sw = 0;                    /* and no digits read */
  475. X
  476. X    while (!exitflag)                /* until end of command string */
  477. X        {
  478. X        if (getcmdc0(trace_sw) == '^')        /* interpret next char as corresp. control char */
  479. X            cmdc = getcmdc(trace_sw) & 0x1f;
  480. X
  481. X        if (isdigit(cmdc))        /* process number */
  482. X            {                    /* this works lousy for hex but so does TECO-11 */
  483. X            if (cmdc - '0' >= ctrl_r) ERROR(E_ILN);                /* invalid digit */
  484. X            if (!(digit_sw++)) esp->val1 = cmdc - '0';            /* first digit */
  485. X            else esp->val1 = esp->val1 * ctrl_r + cmdc - '0';    /* other digits */
  486. X            esp->flag1++;        /* indicate a value read in */
  487. X            }
  488. X
  489. X    /* not a digit: dispatch on character */
  490. X
  491. X        else
  492. X            {
  493. X            digit_sw = 0;
  494. X            switch (mapch_l[cmdc])
  495. X                {
  496. X
  497. X/* characters ignored */
  498. X
  499. X                case CR:
  500. X                case LF:
  501. X                case VT:
  502. X                case FF:
  503. X                case ' ':
  504. X                    break;
  505. X /* ESC: one absorbs argument, two terminate current level */
  506. X
  507. X                case ESC:
  508. X                    if (peekcmdc(ESC))    /* if next char is an ESC */
  509. X                        {
  510. X                        if (msp <= &mstack[0]) exitflag = 1;    /* pop stack; if empty, terminate */
  511. X                        else --msp;
  512. X                        }
  513. X                    else
  514. X                        {
  515. X                        esp->flag1 = 0;        /* else consume argument */
  516. X                        esp->op = OP_START;
  517. X                        }
  518. X                    break;
  519. X
  520. X/* skip comments */
  521. X
  522. X                case '!':
  523. X                    while (getcmdc(trace_sw) != '!');
  524. X                    break;
  525. X
  526. X/* modifiers */
  527. X
  528. X                case '@':
  529. X                    atflag++;
  530. X                    break;
  531. X
  532. X                case ':':
  533. X                    if (peekcmdc(':'))        /* is it "::" ? */
  534. X                        {
  535. X                        getcmdc(trace_sw);    /* yes, skip 2nd : */
  536. X                        colonflag = 2;        /* and set flag to show 2 */
  537. X                        }
  538. X                    else colonflag = 1;        /* otherwise just 1 colon */
  539. X                    break;
  540. X
  541. X/* trace control */
  542. X
  543. X                case '?':
  544. X                    trace_sw = !(trace_sw);
  545. X                    break;
  546. X
  547. X/* values */
  548. X
  549. X                case '.':
  550. X                    esp->val1 = dot;
  551. X                    esp->flag1 = 1;
  552. X                    break;
  553. X
  554. X                case 'z':
  555. X                    esp->val1 = z;
  556. X                    esp->flag1 = 1;
  557. X                    break;
  558. X
  559. X                case 'b':
  560. X                    esp->val1 = 0;
  561. X                    esp->flag1 = 1;
  562. X                    break;
  563. X             case 'h':
  564. X                    esp->val1 = z;
  565. X                    esp->val2 = 0;
  566. X                    esp->flag2 = esp->flag1 = 1;
  567. X                    esp->op = OP_START;
  568. X                    break;
  569. X
  570. X                case CTL (S):        /* -length of last insert, etc. */
  571. X                    esp->val1 = ctrl_s;
  572. X                    esp->flag1 = 1;
  573. X                    break;
  574. X
  575. X                case CTL (Y):        /* .-^S, . */
  576. X                    esp->val1 = dot + ctrl_s;
  577. X                    esp->val2 = dot;
  578. X                    esp->flag1 = esp->flag2 = 1;
  579. X                    esp->op = OP_START;
  580. X                    break;
  581. X
  582. X                case '(':
  583. X                    if (++esp > &estack[ESTACKSIZE-1]) ERROR(E_PDO);
  584. X                    esp->flag2 = esp->flag1 = 0;
  585. X                    esp->op = OP_START;
  586. X                    break;
  587. X
  588. X                case CTL (E):                /* form feed flag */
  589. X                    esp->val1 = ctrl_e;
  590. X                    esp->flag1 = 1;
  591. X                    break;
  592. X
  593. X                case CTL (N):                /* eof flag */
  594. X                    esp->val1 = infile->eofsw;
  595. X                    esp->flag1 = 1;
  596. X                    break;
  597. X
  598. X                case CTL (^):                /* value of next char */
  599. X                    esp->val1 = getcmdc(trace_sw);
  600. X                    esp->flag1 = 1;
  601. X                    break;
  602. X
  603. X/* date, time */
  604. X
  605. X                case CTL (B):
  606. X                case CTL (H):
  607. X                    gettimeofday(&timevalue, &tzvalue);
  608. X                    timeptr = localtime(&timevalue.tv_sec);
  609. X                    esp->val1 = (cmdc == CTL (B)) ?
  610. X                            timeptr->tm_year * 512   + timeptr->tm_mon * 32  + timeptr->tm_mday :
  611. X                            timeptr->tm_hour * 1800  + timeptr->tm_min * 30  + timeptr->tm_sec/2;
  612. X                    esp->flag1 = 1;
  613. X                    make_buffer(&timbuf);        /* make a time buffer */
  614. X                    timestring = asctime(timeptr);
  615. X                    for (timbuf.z = 0; timbuf.z < 24; timbuf.z++)        /* copy character string */
  616. X                        timbuf.f->ch[timbuf.z] = *(timestring + timbuf.z);
  617. X                    break;
  618. X /* number of characters to matching ( ) { } [ ] */
  619. X
  620. X                case CTL (P):
  621. X                    do_ctlp();
  622. X                    break;
  623. X
  624. X/* none of the above: incorporate the last value into the expression */
  625. X
  626. X                default:
  627. X                    if (esp->flag1)                /* if a value entered */
  628. X                        {
  629. X                        switch (esp->op)
  630. X                            {
  631. X                            case OP_START:
  632. X                                break;
  633. X
  634. X                            case OP_ADD:
  635. X                                esp->val1 += esp->exp;
  636. X                                esp->op = OP_START;
  637. X                                break;
  638. X
  639. X                            case OP_SUB:
  640. X                                esp->val1 = esp->exp - esp->val1;
  641. X                                esp->op = OP_START;
  642. X                                break;
  643. X
  644. X                            case OP_MULT:
  645. X                                esp->val1 *= esp->exp;
  646. X                                esp->op = OP_START;
  647. X                                break;
  648. X
  649. X                            case OP_DIV:
  650. X                                esp->val1 = (esp->val1) ? esp->exp / esp->val1 : 0;
  651. X                                esp->op = OP_START;
  652. X                                break;
  653. X
  654. X                            case OP_AND:
  655. X                                esp->val1 &= esp->exp;
  656. X                                esp->op = OP_START;
  657. X                                break;
  658. X
  659. X                            case OP_OR:
  660. X                                esp->val1 |= esp->exp;
  661. X                                esp->op = OP_START;
  662. X                                break;
  663. X                            }
  664. X                    }                /* end of "if a new value" */
  665. X
  666. X                exec_cmds1();    /* go do the command */
  667. X                }        /* end of command dispatch */
  668. X            }        /* end of "not a digit" */
  669. X        }        /* end of "while" command loop */
  670. X    return;
  671. X    }            /* end of exec_cmdstr */
  672. X
  673. X
  674. END_OF_te_exec0.c
  675. if test 5458 -ne `wc -c <te_exec0.c`; then
  676.     echo shar: \"te_exec0.c\" unpacked with wrong size!?
  677. fi
  678. # end of overwriting check
  679. fi
  680. echo shar: Extracting \"te_main.c\" \(5907 characters\)
  681. if test -f te_main.c ; then 
  682.   echo shar: Will not over-write existing file \"te_main.c\"
  683. else
  684. sed "s/^X//" >te_main.c <<'END_OF_te_main.c'
  685. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  686. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  687. X/* They may be copied if this copyright notice is included                    */
  688. X
  689. X/* te_main.c  main program  1/14/87 */
  690. X
  691. X/*
  692. X* This is TECO for Ultrix on a Vax.  It is mostly compatible with DEC TECO
  693. X* as explained in the DEC TECO manual.  It was written from a manual for
  694. X* TECO-11 version 34, and so adheres most closely to that version.
  695. X*
  696. X* This program consists of several source files, as follows:
  697. X*
  698. X* te_main.c (this file)        Main program - initialize, read command line and
  699. X*                            startup file, handle errors, high-level read and
  700. X*                            execute command strings.
  701. X*
  702. X* te_defs.h                    Definitions file, to be #included with other files
  703. X*
  704. X* te_data.c                    Global variables
  705. X*
  706. X* te_rdcmd.c                Read in a command string
  707. X*
  708. X* te_exec0.c                First-level command execution - numbers, values,
  709. X*                            assemble expressions
  710. X*
  711. X* te_exec1.c                Most commands
  712. X*
  713. X* te_exec2.c                "E" and "F" commands, and file I/O
  714. X*
  715. X* te_srch.c                    routines associated with "search" commands
  716. X*
  717. X* te_subs.c                    higher-level subroutines
  718. X*
  719. X* te_utils.c                lower-level subroutines
  720. X*
  721. X* te_chario.c                keyboard (stdin), typeout (stdout), suspend
  722. X*
  723. X* te_window.c                display window and display special functions
  724. X*
  725. X* These routines should be compiled and linked to form the TECO executable.
  726. X*/
  727. X
  728. X#include "te_defs.h"
  729. X
  730. Xmain(argc, argv)
  731. X    int argc;            /* arg count */
  732. X    char *argv[];        /* array of string pointers */
  733. X    {
  734. X    int i;
  735. X
  736. X    save_args(argc, argv, &qreg[36]);    /* copy command line to Qz */
  737. X    read_startup();                        /* read startup file */
  738. X    setup_tty(TTY_ON);        /* set tty to CBREAK, no echo, asynch mode */
  739. X    window(WIN_INIT);        /* initialize screen-image buffer */
  740. X    get_term_par();            /* set terminal screen-size parameters */
  741. X
  742. X/* set up error restart */
  743. X    if (err = setjmp(xxx))
  744. X        {
  745. X        if (err == E_EFI) goto quit;        /* EOF from standard input - clean up and exit */
  746. X        printf("\015\012?  %s", errors[err-1]);
  747. X        if (err == E_SRH) print_string(SERBUF);            /* print unfulfilled search string */
  748. X        else if ((err == E_FNF) || (err == E_COF) || (err == E_AMB)) print_string(FILBUF);    /* or file string */
  749. X        crlf();
  750. X        eisw = 0;                /* stop indirect command execution */
  751. X        et_val &= ~(ET_CTRLC | ET_NOWAIT | ET_CTRLO | ET_NOECHO);    /* reset ^C trap, read w/o wait, ^O (unused), no echo */
  752. X        if (et_val & ET_QUIT)    /* if ET has "quit on error" set, exit (phone home) */
  753. X            {
  754. X            cleanup();            /* reset screen, keyboard, output files */
  755. X            exit(1);            /* and exit */
  756. X            }
  757. X        }
  758. X
  759. X/* forever: read and execute command strings */
  760. X
  761. X    for (exitflag = 1; exitflag >= 0; )        /* "exit" sets exitflag to -1; ^C to -2; "hangup" to -3 */
  762. X        {
  763. X        window(WIN_REFR);                /* display the buffer */
  764. X        free_blist(insert_p);            /* free any storage from failed insert */
  765. X        free_blist(dly_freebuff);        /* return any delayed cells */
  766. X        insert_p = dly_freebuff = NULL;
  767. X        et_val &= ~ET_QUIT;                /* clear "abort on error" */
  768. X        if (read_cmdstr()) goto quit;
  769. X        exitflag = 0;                    /* enable ^C detector */
  770. X        if (!WN_scroll) window(WIN_REDRAW);        /* if not in scroll mode, force full redraw on first ^W or nW */
  771. X        exec_cmdstr();
  772. X        }
  773. X
  774. X    if (exitflag == -2) ERROR(E_XAB);        /* ^C detected during execution */
  775. X    else if (exitflag == -3) panic();        /* hangup during execution: save buffer and close files */
  776. X
  777. X/* exit from program */
  778. X
  779. X  quit:
  780. X    ev_val = es_val = 0;    /* no last one-line window */
  781. X    window(WIN_REFR);        /* last display */
  782. X    cleanup();                /* reset screen, terminal, output files */
  783. X    exit(0);                /* and quit */
  784. X    }
  785. X /* reset screen state, keyboard state; remove open output files */
  786. X
  787. Xcleanup()
  788. X    {
  789. X    window(WIN_OFF);            /* restore screen */
  790. X    setup_tty(TTY_OFF);            /* restore terminal */
  791. X    kill_output(&po_file);        /* kill any open primary output file */
  792. X    kill_output(&so_file);        /* and secondary file */
  793. X    }
  794. X
  795. X
  796. X/* print string for error message */
  797. X/* argument is subscript of a qreg qh, prints text from that buffer */
  798. X
  799. Xprint_string(arg)
  800. X    int arg;
  801. X    {
  802. X    int i, c;
  803. X    struct buffcell *p;
  804. X
  805. X    type_char('"');
  806. X    for (p = qreg[arg].f, c = 0, i = 0; i < qreg[arg].z; i++)
  807. X        {
  808. X        if (!p->ch[c]) break;
  809. X        type_char(p->ch[c]);
  810. X        if (++c > CELLSIZE-1)
  811. X            {
  812. X            p = p->f;
  813. X            c = 0;
  814. X            }
  815. X        }
  816. X    type_char('"');
  817. X    }
  818. X /* copy invocation command line to a text buffer */
  819. X
  820. Xsave_args(argc, argv, q)
  821. X    int argc;
  822. X    char *argv[];
  823. X    struct qh *q;
  824. X    {
  825. X    char c;
  826. X    struct qp ptr;
  827. X
  828. X    make_buffer(q);                /* attach a text buffer */
  829. X    ptr.p = q->f;                /* initialize pointer to output string */
  830. X    ptr.c = q->z = 0;            /* and output char count */
  831. X    for (; argc > 0; argv++, argc--)    /* for each arg */
  832. X        {
  833. X        while ( ((c = *((*argv)++)) != '\0') && (q->z < CELLSIZE-1) )
  834. X            {
  835. X            ptr.p->ch[ptr.c] = c;        /* copy char to q-reg */
  836. X            fwdcx(&ptr);
  837. X            ++q->z;                        /* count characters */
  838. X            }
  839. X        if (argc > 1)                    /* if not last argument... */
  840. X            {
  841. X            ptr.p->ch[ptr.c] = ' ';        /* space to separate arguments */
  842. X            fwdcx(&ptr);
  843. X            }
  844. X        }
  845. X    }
  846. X
  847. X
  848. X
  849. X/* routine to read startup file */
  850. X
  851. Xchar startup_name[] = "/.tecorc";        /* name of startup file */
  852. X
  853. Xread_startup()
  854. X    {
  855. X    char *hp, *getenv();
  856. X    char fn[CELLSIZE];        /* filename storage */
  857. X    int i;
  858. X
  859. X/* look for ".tecorc" in current directory first */
  860. X
  861. X    if (!(eisw = fopen(&startup_name[1], "r")))
  862. X        {
  863. X        if (hp = getenv("HOME"))    /* if not found, look in home directory */
  864. X            {
  865. X            for (i = 0; i < CELLSIZE; i++) if (!(fn[i] = *(hp++))) break;    /* copy until trailing null */
  866. X            for (hp = &startup_name[0]; i < CELLSIZE; i++) if (!(fn[i] = *(hp++))) break;
  867. X            eisw = fopen(fn, "r");        /* set eisw if file found, or not if not */
  868. X            }
  869. X        }
  870. X    }
  871. X /* routine to get terminal height and width from termcap */
  872. X
  873. Xget_term_par()
  874. X    {
  875. X    char buff[1024];    /* termcap buffer */
  876. X    char *pname;        /* pointer to name of terminal */
  877. X    extern char *getenv();
  878. X
  879. X    if (pname = getenv("TERM"))        /* read terminal name */
  880. X        {
  881. X        tgetent(buff, pname);        /* get entry */
  882. X        set_term_par(tgetnum("li"), tgetnum("co"));    /* get #lines and #columns and set params */
  883. X        }
  884. X    }
  885. X
  886. END_OF_te_main.c
  887. if test 5907 -ne `wc -c <te_main.c`; then
  888.     echo shar: \"te_main.c\" unpacked with wrong size!?
  889. fi
  890. # end of overwriting check
  891. fi
  892. echo shar: Extracting \"te_rdcmd.c\" \(7303 characters\)
  893. if test -f te_rdcmd.c ; then 
  894.   echo shar: Will not over-write existing file \"te_rdcmd.c\"
  895. else
  896. sed "s/^X//" >te_rdcmd.c <<'END_OF_te_rdcmd.c'
  897. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  898. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  899. X/* They may be copied if this copyright notice is included                    */
  900. X
  901. X/* te_rdcmd.c  read in the command string  12/20/85 */
  902. X#include "te_defs.h"
  903. X
  904. Xint ccount;                /* count of chars read in */
  905. X
  906. Xint read_cmdstr()
  907. X    {
  908. X    char c;                /* temporary character */
  909. X    int i;                /* temporary */
  910. X
  911. X    goto prompt;
  912. X
  913. X  restart:                    /* prompt again: new line */
  914. X    if (!eisw && !inp_noterm) crlf();        /* if input not from a file */
  915. X  prompt:                    /* issue prompt */
  916. X    if (!eisw && !inp_noterm)
  917. X        {
  918. X        reset_ctlo();        /* reset any ^O */
  919. X        type_char('*');
  920. X        }
  921. X    ccount = 0;
  922. X    lastc = ' ';
  923. X
  924. Xreline:                    /* continue reading */
  925. X    for (;;)            /* loop to read command string chars */
  926. X        {
  927. X        if (!eisw && !inp_noterm)        /* if terminal input */
  928. X            {
  929. X            if ((c = gettty()) == DEL)        /* process rubout */
  930. X                {
  931. X                if (!ccount) goto restart;        /* if at beginning, ignore */
  932. X                --ccount;                        /* decrement char count */
  933. X                backc(&cmdstr);                    /* back up the command-string pointer */
  934. X
  935. X/* look at the character just deleted */
  936. X                if (((c = cmdstr.p->ch[cmdstr.c]) < ' ') && (c != ESC))        /* control chars: set c to char erased */
  937. X                    {
  938. X                    if (c == LF) vt(VT_LINEUP);        /* line up */
  939. X
  940. X                    else if ((c == CR) || (c == TAB))
  941. X                        {
  942. X                        i = find_lasteol();            /* back up to previous line */
  943. X                        type_char(CR);                /* erase current line */
  944. X                        vt(VT_EEOL);
  945. X                        if (i == ccount) type_char('*');        /* if this was line with prompt, retype the prompt */
  946. X                        for (; (t_qp.p != cmdstr.p) || (t_qp.c != cmdstr.c); fwdc(&t_qp))
  947. X                            type_char(t_qp.p->ch[t_qp.c]);        /* retype line: stop before deleted position */
  948. X                        }
  949. X
  950. X                    else
  951. X                        {
  952. X                        vt(VT_BS2);                /* erase ordinary ctrl chars */
  953. X                        char_count -= 2;
  954. X                        }
  955. X                    }
  956. X
  957. X                else
  958. X                    {
  959. X                    vt(VT_BS1);                /* erase printing chars */
  960. X                    char_count--;
  961. X                    }
  962. X                lastc = ' ';        /* disable dangerous last chars */
  963. X                continue;
  964. X                }                    /* end 'rubout' processing */
  965. X
  966. X            else if (c == CTL(U))            /* process "erase current line" */
  967. X                {
  968. X                type_char(CR);                /* erase line */
  969. X                vt(VT_EEOL);
  970. X                if ((ccount -= find_lasteol()) <= 0) goto prompt;    /* back up to last eol: if beginning, restart */
  971. X                cmdstr.p = t_qp.p;            /* put command pointer back to this point */
  972. X                cmdstr.c = t_qp.c;
  973. X                lastc = ' ';
  974. X                continue;                /* and read it again */
  975. X                }
  976. X
  977. X            else            /* not a rubout or ^U */
  978. X                {
  979. X                if (!ccount)        /* if at beginning of line */
  980. X                    {
  981. X                    if (c == '*')        /* save old command string */
  982. X                        {
  983. X                        type_char('*');        /* echo character */
  984. X                        type_char(c = gettty());    /* read reg spec and echo */
  985. X                        i = getqspec(0, c);
  986. X                        free_blist(qreg[i].f);        /* return its previous contents */
  987. X                        qreg[i].f = cbuf.f;            /* put the old command string in its place */
  988. X                        qreg[i].f->b = (struct buffcell *) &qreg[i];
  989. X                        qreg[i].z = cbuf.z;
  990. X                        cbuf.f = NULL;                /* no old command string */
  991. X                        err = 0;                    /* no previous error */
  992. X                        goto restart;
  993. X                        }
  994. X                    else if ((c == '?') && (err))    /* echo previous command string up to error */
  995. X                        {
  996. X                        type_char('?');            /* echo ? */
  997. X                        for (aa.p = cptr.p; aa.p->b->b != NULL; aa.p = aa.p->b);    /* find beginning */
  998. X                        for (aa.c = 0; (aa.p != cptr.p) || (aa.c < cptr.c); fwdc(&aa)) type_char(aa.p->ch[aa.c]);
  999. X                        type_char('?');                /* a final ? */
  1000. X                        err = 0;                /* reset error switch */
  1001. X                        goto restart;
  1002. X                        }
  1003. X                    else if ((c == LF) || (c == CTL (H)))    /* line feed, backspace */
  1004. X                        {
  1005. X                        dot += lines( (c == LF) ? 1 : -1);    /* pointer up or down one line */
  1006. X                        window(WIN_LINE);            /* display one line */
  1007. X                        goto restart;
  1008. X                        }
  1009. X
  1010. X                    else                    /* first real command on a line */
  1011. X                        {
  1012. X                        make_buffer(&cbuf);    /* start a command string if need be */
  1013. X                        cmdstr.p = cbuf.f;    /* set cmdstr to point to start of command string */
  1014. X                        cmdstr.c = 0;
  1015. X                        cbuf.z = 0;            /* no chars in command string now */
  1016. X                        err = 0;            /* clear last error flag */
  1017. X                        }
  1018. X                    }    /* end of "if first char on line" */                
  1019. X
  1020. X
  1021. X/* check ^G-something */
  1022. X
  1023. X                if (lastc == CTL (G))
  1024. X                    {
  1025. X                    if (c == CTL(G))
  1026. X                        {
  1027. X                        cbuf.z = ccount;    /* save count for possible "save in q-reg" */
  1028. X                        goto restart;
  1029. X                        }
  1030. X                    if ((c == '*') || (c == ' '))
  1031. X                        {
  1032. X                        backc(&cmdstr);        /* remove the previous ^G from buffer */
  1033. X                        --ccount;
  1034. X                        crlf();
  1035. X                        retype_cmdstr(c);    /* retype appropriate part of command string */
  1036. X                        lastc = ' ';
  1037. X                        continue;
  1038. X                        }            /* end of ^G* and ^G<sp> processing */
  1039. X                    }            /* end of "last char was ^G" */
  1040. X                }            /* end of "not rubout or ^U */
  1041. X            }            /* end of "if !eisw" */
  1042. X
  1043. X        else            /* if input from indirect file or redirected std input */
  1044. X            {
  1045. X            if (!ccount)    /* first command? */
  1046. X                {
  1047. X                if (!cbuf.f)    /* start a command string if need be */
  1048. X                    {
  1049. X                    cbuf.f = get_bcell();
  1050. X                    cbuf.f->b = (struct buffcell *) &cbuf;
  1051. X                    }
  1052. X                cmdstr.p = cbuf.f;        /* point cmdstr to start of command string */
  1053. X                cbuf.z = cmdstr.c = 0;
  1054. X                }
  1055. X
  1056. X            c = (eisw) ? getc(eisw) : gettty() ;    /* get char */
  1057. X            if (eisw && (c == EOF))            /* if this is end of the indirect command file */
  1058. X                {
  1059. X                fclose(eisw);                /* close the input file */
  1060. X                eisw = 0;                    /* reset the switch */
  1061. X                lastc = ' ';
  1062. X                continue;                    /* and go read more chars */
  1063. X                }
  1064. X            else
  1065. X                {
  1066. X                if ((c == LF) && (lastc != CR) && !(ez_val & EZ_CRLF))    /* LF: store implied CR first */
  1067. X                    {
  1068. X                    cmdstr.p->ch[cmdstr.c] = CR;
  1069. X                    ++ccount;
  1070. X                    fwdcx(&cmdstr);
  1071. X                    }
  1072. X                }
  1073. X            }            /* end of "if redirected std in or eisw" */
  1074. X
  1075. X
  1076. X/* store character in command string */
  1077. X
  1078. X            cmdstr.p->ch[cmdstr.c] = c;        /* store the character */
  1079. X            ++ccount;                        /* keep count of chars */
  1080. X            if (!eisw && !inp_noterm) type_char(c);        /* echo the character */
  1081. X            fwdcx(&cmdstr);                    /* next char pos'n; extend command string if nec */
  1082. X
  1083. X            if ((c == ESC) && (lastc == ESC)) break;    /* stop on 2nd ESC */
  1084. X            if ((c == CTL (C)) && (lastc == CTL (C))) return(-1);    /* immediate exit */
  1085. X            lastc = c;                                /* keep track of last char */
  1086. X            }                    /* end of read-char loop */
  1087. X
  1088. X    cbuf.z = ccount;        /* indicate number of chars in command string */
  1089. X    if (!eisw && !inp_noterm) crlf();        /* final new-line */
  1090. X    return(0);
  1091. X    }                    /* end of read_cmdstr() */
  1092. X
  1093. X/* back up to find most recent CR or LF in entered command string */
  1094. X/* return number of chars backed up */
  1095. X
  1096. Xint find_lasteol()
  1097. X    {
  1098. X    int i;
  1099. X
  1100. X    for (i = 0, t_qp.p = cmdstr.p, t_qp.c = cmdstr.c; (backc(&t_qp)) ; i++)    /* look for beg. of line */
  1101. X        {
  1102. X        if ((t_qp.p->ch[t_qp.c] == CR) || (t_qp.p->ch[t_qp.c] == LF))
  1103. X            {
  1104. X            fwdc(&t_qp);    /* stop short of previous eol */
  1105. X            break;
  1106. X            }
  1107. X        }
  1108. X    char_count = 0;                /* reset tab count */
  1109. X    return(i);
  1110. X    }
  1111. X
  1112. X
  1113. X
  1114. X/* retype command string: entirely (arg = '*') or most recent line (arg = ' ') */
  1115. X
  1116. Xretype_cmdstr(c)
  1117. X    char c;
  1118. X    {
  1119. X    int i;
  1120. X
  1121. X    if (!inp_noterm)    /* if input is really from terminal */
  1122. X        {
  1123. X        if (c == ' ')        /* look for beginning of this line */
  1124. X            i = ccount - find_lasteol();    /* to last eol, and count char's backed up */
  1125. X        else
  1126. X            {
  1127. X            t_qp.p = cbuf.f;    /* retype whole command string */
  1128. X            i = t_qp.c = 0;
  1129. X            }
  1130. X        if (!i) type_char('*');    /* if from beginning, retype prompt */
  1131. X        for (; i < ccount; i++)        /* type command string from starting point */
  1132. X            {
  1133. X            type_char(t_qp.p->ch[t_qp.c]);
  1134. X            fwdc(&t_qp);
  1135. X            }
  1136. X        }
  1137. X    }
  1138. X
  1139. END_OF_te_rdcmd.c
  1140. if test 7303 -ne `wc -c <te_rdcmd.c`; then
  1141.     echo shar: \"te_rdcmd.c\" unpacked with wrong size!?
  1142. fi
  1143. # end of overwriting check
  1144. fi
  1145. echo shar: Extracting \"te_utils.c\" \(5967 characters\)
  1146. if test -f te_utils.c ; then 
  1147.   echo shar: Will not over-write existing file \"te_utils.c\"
  1148. else
  1149. sed "s/^X//" >te_utils.c <<'END_OF_te_utils.c'
  1150. X/* TECO for Ultrix   Copyright 1986 Matt Fichtenbaum                        */
  1151. X/* This program and its components belong to GenRad Inc, Concord MA 01742    */
  1152. X/* They may be copied if this copyright notice is included                    */
  1153. X
  1154. X/* te_utils.c utility subroutines  10/28/85 */
  1155. X
  1156. X#include "te_defs.h"
  1157. X
  1158. X/* routines to handle storage */
  1159. X/* get a buffcell */
  1160. X/* if there are no buffcells available, call malloc for more storage */
  1161. X
  1162. Xstruct buffcell *get_bcell()
  1163. X    {
  1164. X    char *malloc();
  1165. X    struct buffcell *p;
  1166. X    int i;
  1167. X
  1168. X    if (freebuff == NULL)
  1169. X        {
  1170. X        p = (struct buffcell *) malloc(BLOCKSIZE);
  1171. X        if (!p) ERROR(E_MEM);
  1172. X        else
  1173. X            {
  1174. X            freebuff =  p;                    /* take the given address as storage */
  1175. X            for (i = 0; i < (BLOCKSIZE/sizeof(struct buffcell)) - 1; i++)    /* for all cells in the new block */
  1176. X                (p+i)->f = p+i+1;            /* chain the forward pointers together */
  1177. X            (p+i)->f = NULL;                /* make the last one's forward pointer NULL */
  1178. X            }
  1179. X        }
  1180. X
  1181. X    p = freebuff;                /* cut out head of "free" list */
  1182. X    freebuff = freebuff->f;
  1183. X    p->f = p->b = NULL;
  1184. X    return(p);
  1185. X    }
  1186. X
  1187. X
  1188. X/* free a list of buffcells */
  1189. Xfree_blist(p)
  1190. X    struct buffcell *p;
  1191. X    {
  1192. X    struct buffcell *t;
  1193. X
  1194. X    if (p != NULL)
  1195. X    {
  1196. X        for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */
  1197. X        t->f = freebuff;        /* put ret'd list at head of "free" list */
  1198. X        freebuff = p;
  1199. X        }
  1200. X    }
  1201. X /* free a list of buffcells to the "delayed free" list */
  1202. Xdly_free_blist(p)
  1203. X    struct buffcell *p;
  1204. X    {
  1205. X    struct buffcell *t;
  1206. X
  1207. X    if (p != NULL)
  1208. X    {
  1209. X        for (t = p; t -> f != NULL; t = t -> f); /* find end of ret'd list */
  1210. X        t->f = dly_freebuff;        /* put ret'd list at head of "free" list */
  1211. X        dly_freebuff = p;
  1212. X        }
  1213. X    }
  1214. X
  1215. X
  1216. X
  1217. X/* get a cell */
  1218. X/* if there are no cells available, get a buffcell and make more */
  1219. X
  1220. Xstruct qp *get_dcell()
  1221. X    {
  1222. X    struct qp *t;
  1223. X    int i;
  1224. X
  1225. X    if (freedcell == NULL)
  1226. X        {
  1227. X        t = freedcell = (struct qp *) get_bcell();    /* get a buffcell */
  1228. X        for (i = 0; i < (sizeof(struct buffcell)/sizeof(struct qp)) - 1; i++)
  1229. X            {
  1230. X            (t+i)->f = t+i+1;    /* chain the fwd pointers together */
  1231. X            (t+i)->f = NULL;    /* make the last one's forward pointer NULL */
  1232. X            }
  1233. X        }
  1234. X
  1235. X    t = freedcell;                /* cut out head of "free" list */
  1236. X    freedcell = (struct qp *) freedcell->f;
  1237. X    t->f =  NULL;
  1238. X    return(t);
  1239. X    }
  1240. X
  1241. X
  1242. X/* free a list of cells */
  1243. Xfree_dlist(p)
  1244. X    struct qp *p;
  1245. X    {
  1246. X    struct qp *t;
  1247. X
  1248. X    if (p != NULL)
  1249. X        {
  1250. X        for (t = p; t->f != NULL; t = t->f); /* find end of ret'd list */
  1251. X        t->f = freedcell;    /* put ret'd list at head of "free" list */
  1252. X        freedcell = p;
  1253. X        }
  1254. X    }
  1255. X /* build a buffer:  called with address of a qh */
  1256. X/* if no buffer there, get a cell and link it in */
  1257. Xmake_buffer(p)
  1258. X    struct qh *p;
  1259. X    {
  1260. X    if (!(p->f))
  1261. X        {
  1262. X        p->f = get_bcell();
  1263. X        p->f->b = (struct buffcell *) p;
  1264. X        }
  1265. X    }
  1266. X
  1267. X
  1268. X/* routines to advance one character forward or backward */
  1269. X/* argument is the address of a qp */
  1270. X/* fwdc, backc return 1 if success, 0 if beyond extremes of buffer) */
  1271. X/* fwdcx extends buffer if failure */
  1272. X
  1273. Xint fwdc(arg)
  1274. X    struct qp *arg;
  1275. X    {
  1276. X    if ((*arg).c >= CELLSIZE-1)        /* test char count for max */
  1277. X        {
  1278. X        if ((*arg).p->f == NULL) return(0);        /* last cell: fail */
  1279. X        else
  1280. X            {
  1281. X            (*arg).p = (*arg).p->f;    /* chain through list */
  1282. X            (*arg).c = 0;            /* and reset char count */
  1283. X            }
  1284. X        }
  1285. X    else ++(*arg).c;                /* otherwise just incr char count */
  1286. X    ++(*arg).dot;
  1287. X    return(1);
  1288. X    }
  1289. X
  1290. Xfwdcx(arg)
  1291. X    struct qp *arg;
  1292. X    {
  1293. X    if ((*arg).c >= CELLSIZE-1)        /* test char count for max */
  1294. X        {
  1295. X        if ((*arg).p->f == NULL)    /* last cell: extend */
  1296. X            {
  1297. X            (*arg).p->f = get_bcell();
  1298. X            (*arg).p->f->b = (*arg).p;
  1299. X            }
  1300. X        (*arg).p = (*arg).p->f;        /* chain through list */
  1301. X        (*arg).c = 0;                /* and reset char count */
  1302. X        }
  1303. X    else ++(*arg).c;                /* otherwise just incr char count */
  1304. X    ++(*arg).dot;
  1305. X    return(1);
  1306. X    }
  1307. X int backc(arg)
  1308. X    struct qp *arg;
  1309. X    {
  1310. X    if ((*arg).c <= 0)            /* test char count for min */
  1311. X        {
  1312. X        if ((*arg).p->b->b == NULL) return(0);        /* first cell: fail */
  1313. X        else
  1314. X            {
  1315. X            (*arg).p = (*arg).p->b;    /* chain through list */
  1316. X            (*arg).c = CELLSIZE-1;    /* reset char count */
  1317. X            }
  1318. X        }
  1319. X    else --(*arg).c;                /* otherwise just decr char count */
  1320. X    --(*arg).dot;
  1321. X    return(1);
  1322. X    }
  1323. X
  1324. X
  1325. X/* set up a pointer to a particular text buffer position */
  1326. X
  1327. Xset_pointer(pos, ptr)    /* first arg is position, 2nd is addr of pointer */
  1328. X    int pos;
  1329. X    struct qp *ptr;
  1330. X    {
  1331. X    struct buffcell *t;
  1332. X    int i;
  1333. X
  1334. X    if (!buff.f)
  1335. X        {
  1336. X        buff.f = get_bcell();            /* if no text buffer, make one    */
  1337. X        buff.f->b = (struct buffcell *) &buff;
  1338. X        }
  1339. X    for (i = pos/CELLSIZE, t = buff.f; (i > 0) && (t->f != NULL); i--) t = t->f;
  1340. X    ptr->p = t;
  1341. X    ptr->c = pos % CELLSIZE;
  1342. X    ptr->dot = pos;
  1343. X    ptr->z = z;
  1344. X    }
  1345. X /* routines to get next character from command buffer        */
  1346. X/* getcmdc0, when reading beyond command string, pops        */
  1347. X/* macro stack and continues.                                */
  1348. X/* getcmdc, in similar circumstances, reports an error        */
  1349. X/* if pushcmdc() has returned any chars, read them first    */
  1350. X/* routines type characters as read, if argument != 0        */
  1351. X
  1352. Xchar getcmdc0(trace)
  1353. X    {
  1354. X    while (cptr.dot >= cptr.z)        /* if at end of this level, pop macro stack */
  1355. X        {
  1356. X        if (--msp < &mstack[0])        /* pop stack; if top level        */
  1357. X            {
  1358. X            msp = &mstack[0];        /* restore stack pointer    */
  1359. X            cmdc = ESC;                /* return an ESC (ignored)        */
  1360. X            exitflag = 1;            /* set to terminate execution    */
  1361. X            return(cmdc);            /* exit "while" and return */
  1362. X            }
  1363. X        }
  1364. X    cmdc = cptr.p->ch[cptr.c++];        /* get char */
  1365. X    ++cptr.dot;                            /* increment character count */
  1366. X    if (trace) type_char(cmdc);            /* trace */
  1367. X    if (cptr.c > CELLSIZE-1)            /* and chain if need be */
  1368. X        {
  1369. X        cptr.p = cptr.p->f;
  1370. X        cptr.c = 0;
  1371. X        }
  1372. X    return(cmdc);
  1373. X    }
  1374. X
  1375. X
  1376. Xchar getcmdc(trace)
  1377. X    {
  1378. X    if (cptr.dot++ >= cptr.z) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
  1379. X    else
  1380. X        {
  1381. X        cmdc = cptr.p->ch[cptr.c++];    /* get char */
  1382. X        if (trace) type_char(cmdc);        /* trace */
  1383. X        if (cptr.c > CELLSIZE-1)        /* and chain if need be */
  1384. X            {
  1385. X            cptr.p = cptr.p->f;
  1386. X            cptr.c = 0;
  1387. X            }
  1388. X        }
  1389. X    return(cmdc);
  1390. X    }
  1391. X
  1392. X
  1393. X/* peek at next char in command string, return 1 if it is equal (case independent) to argument */
  1394. Xint peekcmdc(arg)
  1395. X    char arg;
  1396. X    {
  1397. X    return(((cptr.dot < cptr.z) && (mapch_l[cptr.p->ch[cptr.c]] == mapch_l[arg])) ? 1 : 0);
  1398. X    }
  1399. X
  1400. END_OF_te_utils.c
  1401. if test 5967 -ne `wc -c <te_utils.c`; then
  1402.     echo shar: \"te_utils.c\" unpacked with wrong size!?
  1403. fi
  1404. # end of overwriting check
  1405. fi
  1406. echo shar: Extracting \"teco.doc\" \(7799 characters\)
  1407. if test -f teco.doc ; then 
  1408.   echo shar: Will not over-write existing file \"teco.doc\"
  1409. else
  1410. sed "s/^X//" >teco.doc <<'END_OF_teco.doc'
  1411. XTECO for Ultrix            Matt Fichtenbaum    January 12, 1987
  1412. X
  1413. X     This TECO is almost compatible with "Standard TECO" as described in
  1414. XDEC literature.  It differs in its display support and interaction with the
  1415. Xoperating system, and in the omission of a few less-frequently-used features.
  1416. XA few of its features are extensions not found in Standard TECO.
  1417. X
  1418. X     The following is a brief comparison between this TECO and Standard
  1419. XTECO version 34, the last for which I have notes.
  1420. X
  1421. X
  1422. XMissing features:
  1423. X
  1424. X   ^F (console switch register)
  1425. X   EG (exit and execute system command)
  1426. X   EH (help flag)
  1427. X   EO (version)
  1428. X   ET & 16 (cancel ^O on output)
  1429. X   ET & 64 (detach)
  1430. X   EU (upper/lower case flag)
  1431. X   backward paging in file (negative arguments to P, N, etc.)
  1432. X
  1433. X
  1434. XNew features:
  1435. X
  1436. X   EQtext$    pass "text" as a command to the shell.  The command is executed
  1437. X   or        in a Unix subshell, with standard input, output, and error
  1438. X   @EQ/text/    connected to the terminal (i.e., unchanged from TECO's setup).
  1439. X
  1440. X   nEQtext$    pass "text" as a command to the shell.  The command is executed
  1441. X   or        in a Unix subshell.  The command's standard input is the
  1442. X   m,nEQtext$    specified text ("n" lines or "m,n" characters) from TECO's
  1443. X   (and "@"    buffer, and its standard output replaces the text in q-register
  1444. X   forms)    q#.  This form of the EQ command thus passes text from TECO's
  1445. X        buffer through a Unix command and makes the result available to
  1446. X        TECO.  (The pointer is left after the specified text and ^S is
  1447. X        set appropriately, so ^SDG# after m,nEQcommand$ replaces the
  1448. X        original text with the command's output)
  1449. X
  1450. X   EQ commands    execute same command as previous EQ.  The presence of arguments
  1451. X   with empty    specifies the command's standard input and output, as above.
  1452. X   string (EQ$)
  1453. X
  1454. X   ^P        if the pointer is positioned on one of the characters
  1455. X        ( )  { }  [ ]  < >  " ' then ^P has the value of the number
  1456. X        of characters to the matching character.  Otherwise ^P has
  1457. X        value 0.  Thus ^PC performs the same function as "%" in vi.
  1458. X        (Note: " is considered to match ' )
  1459. X
  1460. X   Q%        buffer containing last Unix command string from EQ command
  1461. X
  1462. X   Q#        buffer containing ASCII text from Unix.  After the commands
  1463. X        "nEQ" and "m,nEQ" this is the standard output from the
  1464. X        invoked command; after ^B or ^H this is the date and time
  1465. X        expressed as a character string.
  1466. X
  1467. X    Text buffer of arbitrary size, using Ultrix virtual memory.
  1468. X    EZ        word with some unrelated one-bit flags, as follows:
  1469. X
  1470. X    1    0: read Unix files: '\n' in file becomes <CR><LF> in
  1471. X           TECO buffer, converted back to '\n' on write.
  1472. X        1: read files literally without this conversion.
  1473. X
  1474. X    2    0: read from file terminates on form feed or EOF
  1475. X        1: read terminates on EOF only; FFs are put into the buffer
  1476. X
  1477. X    4    0: tabs are displayed every 8 columns
  1478. X        1: tabs are displayed every 4 columns
  1479. X
  1480. X    8    0: EWfile$ and EBfile$ open "file.tmp" as output file;
  1481. X           this is renamed to "file" when output file is closed.
  1482. X        1: EWfile$ opens "file" as named - any preexisting file
  1483. X           of this name is immediately deleted.  EBfile$ always
  1484. X           opens "file.tmp."
  1485. X           (This form must be used when the output is to a non-
  1486. X           directory device, e.g. /dev/tty)
  1487. X
  1488. X    16    0: <TAB>text$ inserts a tab, then text
  1489. X        1: <TAB> is ignored as a command
  1490. X
  1491. X    32    0: <LF>, <FF> and <VT> count as line separators for commands
  1492. X           that count lines (nL, nXq, etc.)
  1493. X        1: only <LF> counts as a line separator
  1494. X
  1495. X    64    0: ER or EB commands that specify multiple files cause an error
  1496. X        1: These commands open the first specified files; other files
  1497. X           may be accessed with the EN$ command (see File Expansion, below)
  1498. X
  1499. X
  1500. XThings that work differently
  1501. X
  1502. X   startup    this TECO looks for a file called ".tecorc" in the user's
  1503. X        home directory and then in the current directory.  TECO
  1504. X        does no processing of command line arguments, but the
  1505. X        entire command line is passed to .tecorc in Q-register Z.
  1506. X        .tecorc may treat the command line as it wishes.
  1507. X
  1508. X   EB        EBfile$ opens "file.tmp" for output.  When the file is
  1509. X        successfully closed (EC, EF, EX), the original file is
  1510. X        renamed with a ".bak" suffix and the ".tmp" file is
  1511. X        renamed with the original name (see bit "8" of variable EZ).
  1512. X
  1513. X   ED & 4    When this bit is set, a command that reads the input file
  1514. X        (P, Y, A) stops reading when the number of characters in
  1515. X        the buffer exceeds 16384.  When this bit is clear, the
  1516. X        buffer is expanded without limit.
  1517. X
  1518. X   EN        ENtext$ or @EN/text/ specifies a file specification that is
  1519. X        passed to the shell for expansion into one or more file names.
  1520. X        EN$ or @EN//, with no string specified, fetches the next file
  1521. X        name into the filespec buffer.  If there are no more files
  1522. X        :EN returns 0, EN causes an error.
  1523. X    Filename    When specified in ER or EB commands, filenames that begin with
  1524. X   expansion    the character ~, or that contain any of the characters * ? { [,
  1525. X        are passed to the shell to be expanded.  If exactly one file
  1526. X        matches the specification this file is opened.  If more than one
  1527. X        file matches, the action depends on the setting of bit 64 in
  1528. X        variable EZ: if this bit is 0, TECO reponds with an "ambiguous
  1529. X        file specification" error; if this bit is 1, TECO substitutes
  1530. X        the list of files for the list resulting from the last EN command,
  1531. X        if any, and opens the first file on the list.  Subsequent entries on
  1532. X        this list are fetched to the filespec buffer by the EN$ command,
  1533. X        as above.  EW (output) and EI (indirect command execution) commands
  1534. X        are not expanded in this manner.
  1535. X
  1536. X   window    this TECO's window support is hard-coded for a VT100-type
  1537. X        terminal.  It includes many but not all of the window
  1538. X        functions of Standard TECO.  The following is a summary of
  1539. X        the display features:
  1540. X
  1541. X    0:w    (terminal type)        always 4 (VT100 in ANSI mode)
  1542. X    1:w    (terminal width)    obtained from Ultrix at startup
  1543. X    2:w    (terminal height)    obtained from Ultrix at startup
  1544. X    3:w    (seeall mode)        unimplemented
  1545. X    4:w    (mark)            unimplemented
  1546. X    5:w    (hold mode)        unimplemented
  1547. X    6:w    (screen origin)        read-only parameter
  1548. X    7:w    (split-screen mode)    implemented
  1549. X
  1550. X    ^W    immediate absolute window redraw
  1551. X
  1552. X    nW    (n not 0 or -1000) immediate window redraw, incremental
  1553. X          unless other output commands have been executed and scroll
  1554. X          mode was disabled
  1555. X
  1556. X    -1000W    "forget" that output has occurred
  1557. X
  1558. X    Note:    window functions using other "special" values as arguments
  1559. X          to nW are not implemented.
  1560. X
  1561. X   EV, ES    argument to these is the number of lines to display
  1562. X        (nEV displays 2N-1 lines about the line containing
  1563. X        the pointer).  The character at the pointer is
  1564. X        shown in reverse video.
  1565. X
  1566. X
  1567. XInteractions with Ultrix
  1568. X
  1569. X     Terminal I/O uses stdin and stdout; numerous ioctl's are used to
  1570. Xadjust the terminal driver's modes.  File I/O uses the buffered I/O
  1571. Xfunctions of <stdio.h>.
  1572. X
  1573. X     The time (^H) and date (^B) make use of the system call
  1574. X"gettimeofday" (2).
  1575. X
  1576. X     The EQ and EN commands and the expansion of filenames for the ER
  1577. Xand EB commands spawn child processes that use pipes for interprocess
  1578. Xcommunication.
  1579. X      Teco explicitly handles the following signals:
  1580. X
  1581. X    SIGINT (interrupt)    The "interrupt" character (^C or equivalent)
  1582. X        interrupts an executing Teco command string or macro, and
  1583. X        gives the error "Execution interrupted."  When no command
  1584. X        string is executing this character is not treated specially.
  1585. X
  1586. X    SIGTSTP (suspend)    Teco responds to this signal by restoring
  1587. X        the terminal characteristics to their original values and
  1588. X        then suspending itself.
  1589. X
  1590. X    SIGHUP (hangup)        Teco responds to this signal by attempting
  1591. X        to save the text buffer and any open output files before
  1592. X        exiting.  If there is any text in the buffer, it is written
  1593. X        to the currently- selected output file; if there is no file,
  1594. X        the buffer is written to the file TECO_SAVED.tmp.  Any open
  1595. X        output files are closed, retaining their ".tmp" suffixes.
  1596. X        Unread input is not copied to the output files.
  1597. X
  1598. END_OF_teco.doc
  1599. if test 7799 -ne `wc -c <teco.doc`; then
  1600.     echo shar: \"teco.doc\" unpacked with wrong size!?
  1601. fi
  1602. # end of overwriting check
  1603. fi
  1604. echo shar: Extracting \"teco_data.doc\" \(4567 characters\)
  1605. if test -f teco_data.doc ; then 
  1606.   echo shar: Will not over-write existing file \"teco_data.doc\"
  1607. else
  1608. sed "s/^X//" >teco_data.doc <<'END_OF_teco_data.doc'
  1609. XA few quick comments on the ways teco arranges its internal
  1610. Xdata storage
  1611. X
  1612. X  Teco has two classes of buffer:
  1613. X    1. Text buffer (the text buffer, q-registers, the command string)
  1614. X    2. Other (buffer header, buffer pointer, iteration-stack entry)
  1615. X
  1616. X
  1617. XText buffers
  1618. X
  1619. X  Each text buffer is a linked list of cells; this is a convenient
  1620. Xway to divide a single address space among an arbitrary number of
  1621. Xbuffers of arbitrary size.  Each cell ("struct buffcell") contains a
  1622. Xforward pointer, a backward pointer, and an array of characters.
  1623. XThe teco buffer, each q-register, each entry on the q-register
  1624. Xpushdown list, and the command string are lists of these cells.
  1625. X
  1626. X  Teco maintains a list of free buffer cells, and its storage
  1627. Xallocation routines furnish cells when needed and accept returned
  1628. Xones.  If the list of free cells is empty, teco calls malloc() to
  1629. Xget a block of storage which it then divides into cells.  Teco never
  1630. Xreturns the storage it gets from malloc().
  1631. X
  1632. X  The text buffer is kept in packed form: each cell but the last
  1633. Xcontains the full number of characters.  This makes it easy for teco
  1634. Xto find its way through the buffer but increases the time taken by
  1635. Xinsert and delete.  It might be interesting to add a "count" field
  1636. Xto the buffer cell and allow cells within the buffer to have empty
  1637. Xspaces at the end; this is a possible future modification.
  1638. X
  1639. X
  1640. XOther
  1641. X
  1642. X  Teco uses three types of small data cell - the q-register header
  1643. X("struct qh"), the q-register pointer ("struct qp"), and the macro
  1644. Xiteration list entry ("struct is").  Although defined as separate
  1645. Xstructures, these are really the same basic cell: they are kept as
  1646. Xa list of free cells and cast to the proper definition when needed.
  1647. X
  1648. X  As in the case of text-buffer cells, data cells are supplied by and
  1649. Xreturned to teco's storage allocation routines.  When a data cell is
  1650. Xneeded and no free cells are available, the storage allocator obtains
  1651. Xa text buffer cell and carves it up into smaller cells, thus, the text-
  1652. Xbuffer cell system is the only interface to malloc().
  1653. X
  1654. X  A text-buffer header ("struct qh") consists of a forward pointer that
  1655. Xpoints to the first cell of the buffer, a backward pointer that is NULL,
  1656. Xa count of characters, and an integer value - the "value" of a numeric
  1657. Xq-register.  The teco buffer has a named header named buff; the q-registers
  1658. Xhave an array, named qreg[], of headers.  
  1659. X
  1660. X    NOTE that the "struct qh" and the "struct buffcell" begin
  1661. X    identically: the forward and backward pointers are in
  1662. X    the same locations in both structures.  Teco uses this in
  1663. X    handling lists: because the buffer header appears to be a
  1664. X    buffer cell, inserting a cell at the beginning of a list is
  1665. X    the same as inserting one farther down.  This is probably a
  1666. X    bad implementation and may not work on all machines.
  1667. X
  1668. X  A q-register pointer ("struct qp") points to a place within a text
  1669. Xbuffer or q-register or the command string.  It has a pointer to the
  1670. Xcurrent buffer cell, a value of the current character within the cell,
  1671. Xvalues for the number of characters in the buffer and the number of the
  1672. Xcurrent character, and, if it is a macro-stack entry, a pointer to the
  1673. Xiteration stack for that macro.
  1674. X
  1675. X  A number of q-register pointers are used as general temporaries, for
  1676. Xmoving text within the buffer, outputting text, etc.  A stack of these
  1677. Xpointers, the macro stack mstack[], controls the execution of command
  1678. Xstrings and macros.  The stack's first entry always points to the command
  1679. Xstring, and a new entry is pushed each time a macro is invoked and is
  1680. Xpopped when the macro terminates.
  1681. X
  1682. X  An iteration-stack entry ("struct is") maintains the data needed for
  1683. Xcommand-string or macro iteration.  Each command or macro level can
  1684. Xhave an iteration stack associated with it: this is kept as a linked
  1685. Xlist of iteration-stack entries, and the macro stack entry contains a
  1686. Xpointer to the head of the list.  Each iteration-stack entry contains
  1687. Xforward and backward pointers for the iteration stack, a pointer
  1688. X(cell address, character offset, absolute character count) to the
  1689. Xcommand that starts the iteration, a count of iterations remaining,
  1690. Xand a flag for definite/indefinite iteration.
  1691. X
  1692. X  An iteration stack is created for a particular command or macro level
  1693. Xthe first time that a loop is encountered at that level.  The cells of
  1694. Xthe stack are not reclaimed but are reused the next time an iteration
  1695. Xoccurs at that command level.
  1696. X
  1697. X  The data definitions specify two more data-structure types, a macro
  1698. Xstack entry ("struct ms") and a buffer header list entry ("struct bh").
  1699. XThese are not used at present.
  1700. X
  1701. END_OF_teco_data.doc
  1702. if test 4567 -ne `wc -c <teco_data.doc`; then
  1703.     echo shar: \"teco_data.doc\" unpacked with wrong size!?
  1704. fi
  1705. # end of overwriting check
  1706. fi
  1707. echo shar: End of archive 1 \(of 4\).
  1708. cp /dev/null ark1isdone
  1709. DONE=true
  1710. for I in 1 2 3 4 ; do
  1711.     if test ! -f ark${I}isdone ; then
  1712.     echo shar: You still need to run archive ${I}.
  1713.     DONE=false
  1714.     fi
  1715. done
  1716. if test "$DONE" = "true" ; then
  1717.     echo You have unpacked all 4 archives.
  1718.     echo "See the *.doc files"
  1719.     rm -f ark[1-9]isdone
  1720. fi
  1721. ##  End of shell archive.
  1722. exit 0
  1723.